// Copyright ©1994-1995 Apple Computer, Inc.
/*----------------------------------------------------------
	Func: CreateLanguagesFrameFromText
	
	Purpose:
		Create the languages frame from some text
		files.
		
		Function first reads in the file defined by
		GlobalsFilePath. The for each symbol in the
		LanguagesSymArray, it will read in a file called
		<sym>Strings.f, where sym in the symbol from the
		array.
		
	Arguments:
		GlobalsFilePath
			full pathname to a file that will be Load'd before
			the language files. Usually used to define
			constants that can be used in the language files.
			
			Can be nil.
			
		LanguagesSymArray
			Array of symbols for the languages to read in. The
			symbol will be used as the slot name for the language.
			
			e.g. ['English, 'French, 'German]
			
			The first file read in will be "EnglishStrings.f", the slot
			in the languages frame will be English.
			
	Returns:
		The languages frame created
----------------------------------------------------------*/

DefGlobalFn('CreateLanguagesFrameFromText, func(GlobalsFilePath, LanguagesSymArray)
begin
	if GlobalsFilePath then
		Load(GlobalsFilePath) ;
	
	local langFrame := {} ;
	
	foreach sym in LanguagesSymArray do
		langFrame.(sym) := load(HOME & SprintObject(sym) & "Strings.f") ;
	langFrame ;
end) ;




/*----------------------------------------------------------
	Func: GetAllResources
	
	Purpose:
		Create an array of binary objects that correspond
		to all resources of a particular type that are
		available.
				
	Arguments:
		ResType
			string for the resource type to check for
		
		NewtType
			type of object to create
					
	Returns:
		An array of the binary objects of resource types.
----------------------------------------------------------*/

DefGlobalFn('GetAllResources, func(ResType, NewtType)
begin
	local result := [];
	local atID := 0 ;	

	// see if we can read in resource id 0, if so increment the
	// next resource id, if not set the id to 128
	try 
		AddArraySlot(result, GetResource(ResType, atID, NewtType)) ;
		atID := 1 ;
		
	onexception |evt.ex.msg| do
		atID := 128 ;
		
	// start at the current resource id (either 1 or 128) and
	// continue reading in resources until an exception occurs
	loop
	begin
		try
			AddArraySlot(result, GetResource(ResType, atID, NewtType)) ;
			atID := atID + 1 ;
		onexception |evt.ex.msg| do
			break ;
	end ;
	result ;
end);


/*----------------------------------------------------------
	Func: CreateLanguagesFrameFromRsrc
	
	Purpose:
		Create the languages frame from a resource file
		
		Function looks for resources of type STR# by name.
		There MUST be one called "Template" which is used
		to construct a frame template.
		
		Then there can be any number of language specific
		STR# resources.
				
	Arguments:
		ResFilePath
			full pathname to the resource file containing the
			required resources.
			
		LanguagesSymArray
			Array of symbols for the languages to read in. The
			symbol will be used as the slot name for the language.
			
			e.g. ['English, 'French, 'German]
			
			This will try to read STR# resources name "Template",
			"English", "French" and "German".
			
	Returns:
		The languages frame created
----------------------------------------------------------*/

DefGlobalFn('CreateLanguagesFrameFromRsrc, func(ResFilePath, LanguagesSymArray)
begin
	// Throw if there are not exactly five languages.
	if Length(LanguagesSymArray) <> 5 then
		Throw('|evt.ex.msg|, "The LanguagesSymArray must be exactly 5 elements long.");

	// the language frame array that will be returned
	local langFrame := {} ;
	foreach sym in LanguagesSymArray do
		langFrame.(sym) := {} ;

	// could use a constant since currently must be exactly 5
	// languages...
	local numLanguages := Length(LanguagesSymArray) ;

	local r := OpenResFileX(ResFilePath) ;

	local locResourceArray := GetAllResources("LOC#", 'binaryObject);

	/* Process the LOC# resources.

		The format of the resource is:
		16 bit count of number of strings ets
		string set 1
		string set 2...
		string set n
		
		string set:
			pathexpression as pascal string
			English as C string
			French as C string
			German as C string
			other1 as C string
			other2 as C string
	*/
	
	local numStringSets ;
	local pathExpr ;
	local tempString ;
	local atIndex ;

	foreach locResource in locResourceArray do
	begin
		// get the number of string sets
		numStringSets := ExtractWord(locResource, 0) ;
		
		atIndex := 2 ;
		//grab each string set
		for stringSet := 1 to numStringSets do
		begin
			// grab the pstring that is the path
			pathExpr := ExtractCString(locResource, atIndex) ;

			// update index counter
			atIndex := atIndex + StrLen(pathExpr) + 1 ;

			// create path expression for following strings
			pathExpr := call Compile("'" & pathExpr) with () ;

			// Get the language strings and jam them.
			// WARNING: this code will ignore 0 length strings
			// there are rare cases where you actually want
			// an empty string for a particular translation. If
			// this is the case, you could modify the code to
			// throw an evt.ex.msg with the appropriate error.
			foreach langSym in LanguagesSymArray do
			begin
				tempString := ExtractCString(locResource, atIndex);
				if StrLen(tempString) > 0 then
					langFrame.(langSym).(pathExpr) := tempString ;
				atIndex := atIndex + StrLen(tempString) + 1
			end;
		end ;
	end ;

	CloseResFileX(r) ;
	langFrame;
end);
